package edu.gznu.ics.fast.common.sshHelper;
import java.io.*;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.jcraft.jsch.*;

/**
 * SSH工具类
 * @author 赵聪慧
 * 2013-4-7
 */
public class sshHelper {

    /**
     * 远程 执行命令并返回结果调用过程 是同步的（执行完才会返回）
     * @param host	主机名
     * @param user	用户名
     * @param psw	密码
     * @param port	端口
     * @param command	命令
     * @return
     */
    public static String exec(String host,String user,String psw,int port,String command){
        String result="";
        Session session =null;
        ChannelExec openChannel =null;
        try {
            JSch jsch=new JSch();
            session = jsch.getSession(user, host, port);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.setPassword(psw);
            session.connect();
            openChannel = (ChannelExec) session.openChannel("exec");
            openChannel.setCommand(command);
            int exitStatus = openChannel.getExitStatus();
            System.out.println(exitStatus);
            openChannel.connect();
            InputStream in = openChannel.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String buf = null;
            while ((buf = reader.readLine()) != null) {
                result+= new String(buf.getBytes("gbk"),"UTF-8")+"    <br>\r\n";
            }
        } catch (JSchException | IOException e) {
            result+=e.getMessage();
        }finally{
            if(openChannel!=null&&!openChannel.isClosed()){
                openChannel.disconnect();
            }
            if(session!=null&&session.isConnected()){
                session.disconnect();
            }
        }
        return result;
    }



    public static void main(String args[]){
        String exec = exec("172.16.99.155", "root", "Aa123456", 22, "sleep 20;ls;");
        System.out.println(exec);
    }
    private void ssh() throws JSchException, IOException {
        //读取服务器磁盘空间信息命令，读取使用率大于 90%的
        String cmd = "df -h | grep -b -E \\(9[1-9]\\%\\)\\|\\(100\\%\\)";
        JSch sshSingleton = new JSch();
//从配置文件中加载用户名和密码
        Properties userProp = new Properties();
        Properties serversProp = new Properties();

            userProp.load(new FileReader("user.properties"));

            serversProp.load(new FileReader("servers.properties"));


        String userName = userProp.getProperty("username");
        String password = userProp.getProperty("password");
//从配置文件中加载服务器信息


        for (Map.Entry<Object, Object> serverProp : serversProp.entrySet()) {
            String name = (String) serverProp.getKey();
            String server = (String) serverProp.getValue();

            System.out.println("Start working on: " + name);
            Session session = sshSingleton.getSession(userName, server);

            session.setPassword(password);
            Properties config = new Properties();
//设置 SSH 连接时不进行公钥确认
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
//打开命令执行管道
            ChannelExec channel = (ChannelExec) session.openChannel("exec");
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    channel.getInputStream()));
            channel.setCommand(cmd);
            channel.connect();
//读取命令输出信息
            String msg;
            while ((msg = in.readLine()) != null) {
                System.out.println(msg);
            }

            channel.disconnect();
            session.disconnect();
        }
    }
    private void sshOrder() throws IOException, JSchException {

        //日志 1 中特殊字符信息
        String uniqeStr = "RunID: 123";
//日志 1 文件位置
        String serverlogFilePath = "/opt/server/log/server.log";
//日志 2 中特殊字符信息
        String jobIdExpr = "id=[0-9]+";
//日志 2 文件位置
        String joblogFilePath = "/opt/server/log/job.log";

        JSch sshSingleton = new JSch();

        Properties userProp = new Properties();
        userProp.load(new FileReader("user.properties"));
        String userName = userProp.getProperty("username");
        String password = userProp.getProperty("password");

        Properties serversProp = new Properties();
        serversProp.load(new FileReader("servers.properties"));

        Pattern p = Pattern.compile(jobIdExpr);
        for (Map.Entry<Object, Object> serverProp : serversProp.entrySet()) {
            String name = (String) serverProp.getKey();
            String server = (String) serverProp.getValue();

            Session session = sshSingleton.getSession(userName, server);
            session.setPassword(password);

            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();

            //打开执行管道
            ChannelExec channel = (ChannelExec) session.openChannel("exec");
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    channel.getInputStream()));
//设置命令，从日志 1 中找出关键字符信息
            channel.setCommand("cat " + serverlogFilePath + " |grep -w "
                    + uniqeStr);
            channel.connect();
            String msg;
            String jobId = null;
            while ((msg = in.readLine()) != null) {
                Matcher m = p.matcher(msg);
                if (m.find()) {
                    jobId = m.group();
                    break;
                }
            }
            //关闭第一个执行管道
            channel.disconnect();

            if (jobId != null) {
                //日志 1 中发现关键字符信息后，在同一服务器中日志文件 2 中继续查找
                System.out.println("found log in jobServer: " + name);

//另外再打开一个新的执行管道
                channel = (ChannelExec) session.openChannel("exec");
                in = new BufferedReader(new InputStreamReader(
                        channel.getInputStream()));
                String cmd = "cat " + joblogFilePath + " |grep -A 10 " + jobId;

                channel.setCommand(cmd);
                channel.connect();
                //输出需要查找的日志信息
                while ((msg = in.readLine()) != null) {
                    System.out.println(msg);
                }

                channel.disconnect();
            }

            session.disconnect();

            if (jobId != null) {
                //已经在这台服务器中找到日志，不需要继续去其他服务器中查找了
                break;
            }
        }
    }
    private void sshUploder() throws IOException, JSchException, SftpException {

        String serverFile = "/opt/log/1.log";
        String localFolder = "C:/tmp";

        String localFile = "C:/tmp/user.xml";
        String serverFolder = "/tmp/";

        JSch sshSingleton = new JSch();

        Properties userProp = new Properties();
        userProp.load(new FileReader("user.properties"));
        String userName = userProp.getProperty("username");
        String password = userProp.getProperty("password");

        String server = "192.168.0.1";
//设置端口
        int port = 22;
        Session session = sshSingleton.getSession(userName, server, port);
        session.setPassword(password);

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        //打开 ftp 管道
        Channel channel = session.openChannel("sftp");
        channel.connect();
        ChannelSftp c = (ChannelSftp) channel;
//转到根目录，便于使用绝对路径来进行文件传输
        c.cd("/");

//从服务器上下载日志文件 1.log 到本地目录 C:/tmp
        c.get(serverFile, localFolder);

//上传配置文件 user.xml 到服务器上，如果服务器上已经存在该文件，则覆盖它
        c.put(localFile, serverFolder, ChannelSftp.OVERWRITE);

        session.disconnect();
    }
}